#define _WIN32_DCOM
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
#include <conio.h>
#include "component\component.h"

void main()
{
    HRESULT hr;

	hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if(FAILED(hr))
        cout << "CoInitializeEx failed. " << endl;

	IPrime* pPrime = 0;
	hr = CoCreateInstance(CLSID_InsideCOM, 0, CLSCTX_LOCAL_SERVER, IID_IPrime, (void**)&pPrime);
	if(FAILED(hr))
	    cout << "CoCreateInstance FAILED" << endl;

	ICallFactory* pCallFactory = 0;
	hr = pPrime->QueryInterface(IID_ICallFactory, (void**)&pCallFactory);
	if(FAILED(hr))
	    cout << "QueryInterface for ICallFactory FAILED" << endl;

	cout << "Release " << pPrime->Release() << endl;

	AsyncIPrime* pAsyncPrime = 0;
	hr = pCallFactory->CreateCall(IID_AsyncIPrime, 0, IID_AsyncIPrime, (IUnknown**)&pAsyncPrime);
	if(FAILED(hr)) 
	    cout << "CreateCall FAILED" << endl;

 	cout << "Release " << pCallFactory->Release() << endl;

	ISynchronize* pSynchronize = 0;
	hr = pAsyncPrime->QueryInterface(IID_ISynchronize, (void**)&pSynchronize);
	if(FAILED(hr))
	    cout << "QueryInterface for AsyncIPrime FAILED" << endl;

	int cancel = 0;

	for(int testnumber = 1000000; testnumber < 1001000; testnumber++)
	{
		int result = 0;

		hr = pAsyncPrime->Begin_IsPrime(testnumber);
		if(FAILED(hr))
		    printf("Begin_IsPrime FAILED hr = %0x\n", hr);

		if(++cancel > 33)
		{
//			hr = CoCancelCall(0, 0);
//			if(FAILED(hr))
//				printf("CoCancelCall FAILED %0x\n", hr);

			ICancelMethodCalls* pCancelMethodCalls = 0;

			hr = pSynchronize->QueryInterface(IID_ICancelMethodCalls, (void**)&pCancelMethodCalls);
			if(SUCCEEDED(hr))
			{

				hr = pCancelMethodCalls->Cancel(0);
				if(hr == RPC_E_CALL_COMPLETE)
					cout << endl << "The call finished executing before it was cancelled." << endl;
				if(hr == S_OK)
					cout << "The cancel request was submitted." << endl;

				cout << "Release " << pCancelMethodCalls->Release() << endl;
			}
			cancel = 0;
		}


		while(pSynchronize->Wait(0, 50) == RPC_S_CALLPENDING)
			cout << "Waiting ";

//
//	0x8007071A should be RPC_E_CALL_CANCELLED
//

		hr = pAsyncPrime->Finish_IsPrime(&result);
		if(hr == 0x8007071A)
			cout << "The call was cancelled " << testnumber << endl;
		else
			if(result)
				cout << endl << testnumber << " is prime." << endl;
		}

	cout << "Release " << pSynchronize->Release() << endl;
	cout << "Release " << pAsyncPrime->Release() << endl;

    CoUninitialize();
}